#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time   : 2022/3/29 15:01
# @Author : 余少琪
import os
import sys
import traceback
import pytest
import time
from utils.other_tools.models import NotificationType
from utils.other_tools.allure_data.allure_report_data import AllureFileClean
from utils.logging_tool.log_control import INFO
from utils.notify.wechat_send import WeChatSend
from utils.notify.ding_talk import DingTalkSendMsg
from utils.notify.send_mail import SendEmail
from utils.notify.lark import FeiShuTalkChatBot
from utils.other_tools.allure_data.error_case_excel import ErrorCaseExcel
from utils import config


def run():
    """
    执行测试运行器的主要函数。
    这个函数负责启动测试执行，生成报告，并根据配置发送通知。
    """
    try:
        # 使用日志记录器记录项目开始执行的信息。
        INFO.logger.info(
            """开始执行{}项目...""".format(config.project_name)
        )

        # 判断现有的测试用例，如果未生成测试代码，则自动生成
        # TestCaseAutomaticGeneration().get_case_automatic()

        # 调用pytest.main执行测试。这些参数用于控制测试的运行和报告的生成。
        pytest.main(['-s', '-W', 'ignore:Module already imported:pytest.PytestWarning',
                     '--alluredir', './report/tmp', "--clean-alluredir"])

        """"
                   --reruns: 失败重跑次数
                   --count: 重复执行次数
                   -v: 显示错误位置以及错误的详细信息
                   -s: 等价于 pytest --capture=no 可以捕获print函数的输出
                   -q: 简化输出信息
                   -m: 运行指定标签的测试用例
                   -x: 一旦错误，则停止运行
                   --maxfail: 设置最大失败次数，当超出这个阈值时，则不会在执行测试用例
                    "--reruns=3", "--reruns-delay=2"
                   """
        # 生成Allure测试报告。
        os.system(r"allure generate ./report/tmp -o ./report/html --clean")
        # 确保报告文件存在
        report_file = "./report/html/index.html"  # 假设index.html是生成后一定会存在的文件
        while not os.path.exists(report_file) or os.path.getsize(report_file) == 0:
            time.sleep(1)  # 等待1秒后再次检查
        # 从报告中获取测试结果统计信息。
        allure_data = AllureFileClean().get_case_count()
        # 指定文件路径
        file_path = "./report/summary.txt"

        # 打开文件并写入数据
        with open(file_path, 'w') as file:
            file.write(f"Passed={allure_data.passed}\n")
            file.write(f"Failed={allure_data.failed}\n")
            file.write(f"Broken={allure_data.broken}\n")
            file.write(f"Skipped={allure_data.skipped}\n")
            file.write(f"Total={allure_data.total}\n")
            file.write(f"Rate={allure_data.pass_rate}%\n")
            file.write(f"Time={allure_data.time} sec\n")
        # 定义通知方法的映射，根据配置决定使用哪种通知方式。
        """notification_mapping = {
            NotificationType.DING_TALK.value: DingTalkSendMsg(allure_data).send_ding_notification,
            NotificationType.WECHAT.value: WeChatSend(allure_data).send_wechat_notification,
            NotificationType.EMAIL.value: SendEmail(allure_data).send_main,
            NotificationType.FEI_SHU.value: FeiShuTalkChatBot(allure_data).post
        }
        # 根据配置发送不同类型的测试结果通知。
        if config.notification_type != NotificationType.DEFAULT.value:
            notify_type = config.notification_type.split(",")
            for i in notify_type:
                notification_mapping.get(i.lstrip(""))()
        # 根据配置生成测试错误案例的Excel报告。
        if config.excel_report:
            ErrorCaseExcel().write_case()
        # 启动Allure报告的本地服务器。
        #os.system(f"allure serve ./report/tmp -h localhost -p 9999")
"""
    except Exception:
        # 捕获任何执行过程中发生的异常，通过邮件发送异常信息。
        e = traceback.format_exc()
        send_email = SendEmail(AllureFileClean.get_case_count())
        send_email.error_mail(e)
        raise


if __name__ == '__main__':
    run()
